package com.emre.daoGenerator.objectClass;

import java.io.*;

import com.emre.daoGenerator.GlobalConstants;
import com.emre.daoGenerator.oracleObject.Field;
import com.emre.daoGenerator.oracleObject.ObjectDefinition;
import com.emre.daoGenerator.oracleObject.OracleDataType;
import com.emre.daoGenerator.utils.DataTypeMethodMapper;
import com.emre.daoGenerator.utils.JavaCodeWriter;
import com.emre.daoGenerator.utils.StringUtils;

public class ObjectClassGenerator 
{
	private ObjectDefinition objectDefinition;
	
	private String path;
	
	public ObjectClassGenerator(ObjectDefinition objectDefinition, String path)
	{
		this.objectDefinition = objectDefinition;
		this.path = path;
	}
	
	public File generate() throws IOException
	{
		JavaCodeWriter writer = new JavaCodeWriter(path + objectDefinition.getObjectName() + ".java");
		
		String packageDeclaration = "package " + GlobalConstants.topLevelPackageName + "." +GlobalConstants.objectsPackageName + ";";
		writer.write(packageDeclaration, 0);
		writer.writeEmptyLine();
		
		writer.write(GlobalConstants.objectClassImportStatements, 0);
		
		writer.write("import " + GlobalConstants.topLevelPackageName + "." + GlobalConstants.beanPackageName + "." + objectDefinition.getBeanClassName() + ";", 0);
		writer.writeEmptyLine();
		
		String classDeclaration = "public class " + objectDefinition.getObjectName() + " implements SqlData, Serializable;";
		writer.write(classDeclaration, 0);
		writer.write("{", 0);
		
		String beanDeclaration = "private " + objectDefinition.getBeanClassName() + " bean;";
		writer.write(beanDeclaration, 1);
		writer.writeEmptyLine();
		
		String constructorDeclaration = "public " + objectDefinition.getObjectName() + "(" + objectDefinition.getBeanClassName() + " bean)";
		writer.write(constructorDeclaration, 1);
		writer.write("{", 1);
		writer.write("this.bean = bean;", 2);
		writer.write("}", 1);
		
		writer.writeEmptyLine();
		
		String getSqlTypeNameMethodDecl = "public String getSQLTypeName() throws SQLException";
		writer.write(getSqlTypeNameMethodDecl, 1);
		writer.write("{", 1);
		writer.write("return \"" + objectDefinition.getFullObjectName() + "\";" , 2);
		writer.write("}", 1);
		
		writer.writeEmptyLine();
		
		String readSqlMethodDeclaration = "public void readSQL(SQLInput stream, String typeName) throws SQLException"; 
		writer.write(readSqlMethodDeclaration, 1);
		writer.write("{", 1);
		writer.write("", 1);
		writer.write("}", 1);
		
		writer.writeEmptyLine();

		String writeSqlMethodDeclaration = "public void writeSQL(SQLOutput stream) throws SQLException";
		writer.write(writeSqlMethodDeclaration, 1);
		writer.write("{", 1);
		for(int i = 0; i < objectDefinition.getFields().size(); i++)
		{
			Field field = objectDefinition.getFields().get(i);

			String getterMethodName = "get" + StringUtils.convertToSentenceCase(field.getName());
			String beanGetExpr = "bean." + getterMethodName + "()";
			
			String ifDecl;
			if(field.getType() != OracleDataType.VARCHAR2)
			{
				ifDecl = "if(" + beanGetExpr +" != null)";
			}
			else
			{
				ifDecl = "if(" + beanGetExpr +" != null && !" + beanGetExpr + ".equals(\"\")" + ")";
			}
			
			writer.write(ifDecl, 2);
			String writeExpr = "stream." + DataTypeMethodMapper.mapDataTypeToWriteMethodName(field.getType()) + "(" + beanGetExpr +");";
			writer.write(writeExpr, 3);
			writer.write("else", 2);
			writer.write("stream.writeObject(null);", 3);
			
			if(i != objectDefinition.getFields().size() - 1)
				writer.writeEmptyLine();
		}
		
		writer.write("}", 1);
		
		
		writer.write("}", 0);
		
		writer.close();
		
		return writer.getFile();
	}
	
}
